#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Location: ./mcpgateway/utils/generate_keys.py
Copyright 2025
SPDX-License-Identifier: Apache-2.0
Authors: Madhav Kandukuri

Utility to generate Ed25519 key pairs for JWT or signing use.
Safely writes PEM-formatted private and public keys to disk.
"""

# Future
from __future__ import annotations

# Standard
# Logging setup
import logging
from pathlib import Path

# Third-Party
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519

logger = logging.getLogger(__name__)


def generate_ed25519_keypair(private_path: Path, public_path: Path) -> None:
    """Generate an Ed25519 key pair and save to PEM files.

    Args:
        private_path: Path to save the private key PEM file.
        public_path: Path to save the public key PEM file.
    """
    private_key = ed25519.Ed25519PrivateKey.generate()
    public_key = private_key.public_key()

    private_bytes = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption(),
    )

    public_bytes = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo,
    )

    private_path.write_bytes(private_bytes)
    public_path.write_bytes(public_bytes)

    print(f"✅ Ed25519 key pair generated:\n  Private: {private_path}\n  Public:  {public_path}")


# ---------------------------------------------------------------------------
# Simplified generator: return private key PEM only
# ---------------------------------------------------------------------------


def generate_ed25519_private_key() -> str:
    """Generate an Ed25519 private key and return PEM string.

    Returns:
        str: PEM-formatted Ed25519 private key.
    """
    private_key = ed25519.Ed25519PrivateKey.generate()
    private_pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption(),
    ).decode()
    return private_pem


# ---------------------------------------------------------------------------
# Helper: derive public key from private PEM
# ---------------------------------------------------------------------------


def derive_public_key_from_private(private_pem: str) -> str:
    """Derive the public key PEM from a given Ed25519 private key PEM string.

    Args:
        private_pem: PEM-formatted Ed25519 private key string.

    Returns:
        str: PEM-formatted Ed25519 public key.

    Raises:
        RuntimeError: If the public key cannot be derived.
    """
    try:
        private_key = serialization.load_pem_private_key(private_pem.encode(), password=None)
        public_key = private_key.public_key()
        public_pem = public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo,
        )
        return public_pem.decode()
    except Exception as e:
        logger.error(f"Error deriving public key from private PEM: {e}")
        raise RuntimeError("Failed to derive public key from private PEM") from e


def main() -> None:
    """Command-line interface to generate Ed25519 private key PEM."""
    private_pem = generate_ed25519_private_key()
    print("Ed25519 private key generated successfully.\n")
    print(private_pem)


if __name__ == "__main__":
    main()
